package com.ybg.block.core.dbapi.service.impl;

import com.ybg.block.core.dbapi.entity.FnsLeague;
import com.ybg.block.core.dbapi.entity.FnsOrg;
import com.ybg.block.core.dbapi.entity.FnsPeer;
import com.ybg.block.core.dbapi.service.FnsPeerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybg.block.core.dbapi.vo.FnsOrgVO;
import com.ybg.block.core.dbapi.vo.FnsPeerVO;
import com.ybg.block.core.dbapi.dao.FnsAppMapper;
import com.ybg.block.core.dbapi.dao.FnsBlockMapper;
import com.ybg.block.core.dbapi.dao.FnsCaMapper;
import com.ybg.block.core.dbapi.dao.FnsChaincodeMapper;
import com.ybg.block.core.dbapi.dao.FnsChannelMapper;
import com.ybg.block.core.dbapi.dao.FnsLeagueMapper;
import com.ybg.block.core.dbapi.dao.FnsOrdererMapper;
import com.ybg.block.core.dbapi.dao.FnsOrgMapper;
import com.ybg.block.core.dbapi.dao.FnsPeerMapper;
import com.ybg.block.core.fabricbak.utils.CacheUtil;
import com.ybg.block.core.fabricbak.utils.DateUtil;
import com.ybg.block.core.fabricbak.utils.DeleteUtil;
import com.ybg.block.core.fabricbak.utils.FabricHelper;
import com.ybg.block.core.fabricbak.utils.FileUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;
//import com.alibaba.dubbo.config.annotation.Service;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yanyu
 * @since 2019-11-21
 */
//@Service(version = "1.0.0", interfaceClass = FnsPeerService.class)
@Service
public class FnsPeerServiceImpl extends ServiceImpl<FnsPeerMapper, FnsPeer> implements FnsPeerService {
    @Autowired
    private FnsLeagueMapper leagueMapper;
    @Autowired
    private FnsOrgMapper orgMapper;
    @Autowired
    private FnsOrdererMapper ordererMapper;
    @Autowired
    private FnsPeerMapper peerMapper;
    @Autowired
    private FnsCaMapper caMapper;
    @Autowired
    private FnsChannelMapper channelMapper;
    @Autowired
    private FnsChaincodeMapper chaincodeMapper;
    @Autowired
    private FnsAppMapper appMapper;
    @Autowired
    private FnsBlockMapper blockMapper;
    @Autowired
    private Environment env;

    @Override
    public int add(FnsPeerVO peer, MultipartFile serverCrtFile, MultipartFile clientCertFile, MultipartFile clientKeyFile) {
        if (StringUtils.isEmpty(peer.getName()) ||
                StringUtils.isEmpty(peer.getLocation()) ||
                StringUtils.isEmpty(peer.getEventHubLocation())) {
            throw new RuntimeException("peer name and location and eventHubLocation can not be null");
        }
        if (StringUtils.isNotEmpty(serverCrtFile.getOriginalFilename()) &&
                StringUtils.isNotEmpty(clientCertFile.getOriginalFilename()) &&
                StringUtils.isNotEmpty(clientKeyFile.getOriginalFilename())) {
            if (saveFileFail(peer, serverCrtFile, clientCertFile, clientKeyFile)) {
                throw new RuntimeException("tls file save fail");
            }
        }
        peer.setDate(DateUtil.getCurrent("yyyy-MM-dd"));
        CacheUtil.removeHome();
        return peerMapper.add(peer);
    }

    @Override
    public int update(FnsPeerVO peer, MultipartFile serverCrtFile, MultipartFile clientCertFile, MultipartFile clientKeyFile) {
        if (StringUtils.isEmpty(serverCrtFile.getOriginalFilename()) ||
                StringUtils.isEmpty(clientCertFile.getOriginalFilename()) ||
                StringUtils.isEmpty(clientKeyFile.getOriginalFilename())) {
            FabricHelper.obtain().removeChaincodeManager(channelMapper.list(peer.getId()), chaincodeMapper);
            CacheUtil.removeHome();
            CacheUtil.removeFlagCA(peer.getId(), caMapper);
            return peerMapper.updateWithNoFile(peer);
        }
        if (saveFileFail(peer, serverCrtFile, clientCertFile, clientKeyFile)) {
            throw new RuntimeException("tls file save fail");
        }
        FabricHelper.obtain().removeChaincodeManager(channelMapper.list(peer.getId()), chaincodeMapper);
        CacheUtil.removeHome();
        CacheUtil.removeFlagCA(peer.getId(), caMapper);
        return peerMapper.update(peer);
    }

    @Override
    public List<FnsPeerVO> listAll() {
        List<FnsPeerVO> peers = peerMapper.listAll();
        for (FnsPeerVO peer : peers) {
            FnsOrg org = orgMapper.get(peer.getOrgId());
            FnsLeague league = leagueMapper.get(org.getLeagueId());
            peer.setLeagueName(league.getName());
            peer.setOrgName(org.getMspId());
            peer.setChannelCount(channelMapper.count(peer.getId()));
        }
        return peers;
    }

    @Override
    public List<FnsPeerVO> listById(int id) {
        return peerMapper.list(id);
    }

    @Override
    public FnsPeerVO get(int id) {
        return peerMapper.get(id);
    }

    @Override
    public int countById(int id) {
        return peerMapper.count(id);
    }

    @Override
    public int count() {
        return peerMapper.countAll();
    }

    @Override
    public int delete(int id) {
        return DeleteUtil.obtain().deletePeer(id, peerMapper, caMapper, channelMapper, chaincodeMapper, appMapper, blockMapper);
    }

    @Override
    public List<FnsOrgVO> listOrgByOrgId(int orgId) {
        FnsLeague league = leagueMapper.get(orgMapper.get(orgId).getLeagueId());
        List<FnsOrgVO> orgs = orgMapper.list(league.getId());
        for (FnsOrgVO org : orgs) {
            org.setLeagueName(league.getName());
        }
        return orgs;
    }

    @Override
    public List<FnsOrgVO> getForPeerAndOrderer() {
        List<FnsOrgVO> orgs =orgMapper.listAll();
        for (FnsOrgVO org : orgs) {
            org.setOrdererCount(ordererMapper.count(org.getId()));
            org.setPeerCount(peerMapper.count(org.getId()));
            org.setLeagueName(leagueMapper.get(org.getLeagueId()).getName());
        }
        return orgs;
    }

    @Override
    public FnsPeerVO resetPeer(FnsPeerVO peer) {
        FnsOrg org = orgMapper.get(peer.getOrgId());
        FnsLeague league = leagueMapper.get(org.getLeagueId());
        FnsPeerVO vo= new FnsPeerVO();
        BeanUtils.copyProperties(peer,vo);
        vo.setLeagueName(league.getName());
        vo.setOrgName(org.getMspId());
        return vo;
    }

    private boolean saveFileFail(FnsPeerVO peer, MultipartFile serverCrtFile, MultipartFile clientCertFile, MultipartFile clientKeyFile) {
        String peerTlsPath = String.format("%s%s%s%s%s%s%s%s",
                env.getProperty("config.dir"),
                File.separator,
                peer.getLeagueName(),
                File.separator,
                peer.getOrgName(),
                File.separator,
                peer.getName(),
                File.separator);
        String serverCrtPath = String.format("%s%s", peerTlsPath, serverCrtFile.getOriginalFilename());
        String clientCertPath = String.format("%s%s", peerTlsPath, clientCertFile.getOriginalFilename());
        String clientKeyPath = String.format("%s%s", peerTlsPath, clientKeyFile.getOriginalFilename());
        peer.setServerCrtPath(serverCrtPath);
        peer.setClientCertPath(clientCertPath);
        peer.setClientKeyPath(clientKeyPath);
        try {
            FileUtil.save(serverCrtFile, clientCertFile, clientKeyFile, serverCrtPath, clientCertPath, clientKeyPath);
        } catch (IOException e) {
            e.printStackTrace();
            return true;
        }
        return false;
    }
}
